<template>
  <div class="graph-management-page">
    <div class="page-header">
      <h2>图数据库管理</h2>
      <p>三维可视化图数据库管理界面</p>
      <div class="header-actions">
        <a-button type="outline" @click="goBack">
          <template #icon><IconArrowLeft /></template>
          返回资源中心
        </a-button>
      </div>
    </div>
    
    <div class="management-container">
      <!-- 控制面板 -->
      <div class="control-panel">
        <div class="panel-section">
          <h3>视图控制</h3>
          <div class="control-group">
            <a-button-group>
              <a-button 
                :type="layoutMode === 'force' ? 'primary' : 'outline'"
                @click="setLayoutMode('force')"
                size="small"
              >
                力导向
              </a-button>
              <a-button 
                :type="layoutMode === 'circle' ? 'primary' : 'outline'"
                @click="setLayoutMode('circle')"
                size="small"
              >
                圆形
              </a-button>
              <a-button 
                :type="layoutMode === 'sphere' ? 'primary' : 'outline'"
                @click="setLayoutMode('sphere')"
                size="small"
              >
                球形
              </a-button>
              <a-button 
                :type="layoutMode === 'grid' ? 'primary' : 'outline'"
                @click="setLayoutMode('grid')"
                size="small"
              >
                网格
              </a-button>
            </a-button-group>
          </div>
          
          <div class="control-group">
            <a-switch 
              v-model="showLabels" 
              @change="toggleLabels"
              size="small"
            />
            <span class="control-label">显示标签</span>
          </div>
          
          <div class="control-group">
            <a-switch 
              v-model="isSimulating" 
              @change="toggleSimulation"
              size="small"
            />
            <span class="control-label">物理模拟</span>
          </div>
        </div>
        
        <div class="panel-section">
          <h3>数据统计</h3>
          <div class="stats-grid">
            <div class="stat-item">
              <div class="stat-value">{{ stats.nodeCount }}</div>
              <div class="stat-label">节点数量</div>
            </div>
            <div class="stat-item">
              <div class="stat-value">{{ stats.edgeCount }}</div>
              <div class="stat-label">关系数量</div>
            </div>
            <div class="stat-item">
              <div class="stat-value">{{ Object.keys(stats.nodeTypes).length }}</div>
              <div class="stat-label">节点类型</div>
            </div>
            <div class="stat-item">
              <div class="stat-value">{{ Object.keys(stats.edgeTypes).length }}</div>
              <div class="stat-label">关系类型</div>
            </div>
          </div>
        </div>
        
        <div class="panel-section">
          <h3>节点信息</h3>
          <div v-if="selectedNodeInfo" class="node-info">
            <div class="info-row">
              <span class="info-label">名称:</span>
              <span class="info-value">{{ selectedNodeInfo.name }}</span>
            </div>
            <div class="info-row">
              <span class="info-label">类型:</span>
              <span class="info-value">{{ selectedNodeInfo.type }}</span>
            </div>
            <div class="info-row">
              <span class="info-label">分类:</span>
              <span class="info-value">{{ selectedNodeInfo.category }}</span>
            </div>
            <div class="info-row">
              <span class="info-label">连接数:</span>
              <span class="info-value">{{ selectedNodeInfo.degree }}</span>
            </div>
          </div>
          <div v-else class="no-selection">
            点击节点查看详细信息
          </div>
        </div>
      </div>
      
      <!-- 3D可视化区域 -->
      <div class="visualization-area">
        <div class="canvas-container">
          <canvas ref="networkCanvas" class="network-canvas"></canvas>
          <div v-if="isLoading" class="loading-overlay">
            <a-spin size="large">
              <template #tip>正在加载图数据库管理界面...</template>
            </a-spin>
          </div>
        </div>
        
        <!-- 工具栏 -->
        <div class="toolbar">
          <a-tooltip content="重置视角">
            <a-button type="text" @click="resetCamera">
              <template #icon><IconRefresh /></template>
            </a-button>
          </a-tooltip>
          <a-tooltip content="重置布局">
            <a-button type="text" @click="resetLayout">
              <template #icon><IconUndo /></template>
            </a-button>
          </a-tooltip>
          <a-tooltip content="全屏">
            <a-button type="text" @click="toggleFullscreen">
              <template #icon><IconFullscreen /></template>
            </a-button>
          </a-tooltip>
          <a-tooltip content="导出图片">
            <a-button type="text" @click="exportImage">
              <template #icon><IconCamera /></template>
            </a-button>
          </a-tooltip>
        </div>
        
        <!-- CSV上传按钮 - 可视化区域左下角 -->
        <div class="csv-upload-button">
          <a-button 
            type="primary" 
            size="large"
            @click="showCsvUploadModal = true"
            class="upload-btn"
          >
            <template #icon><IconUpload /></template>
            知识新增CSV
          </a-button>
        </div>
      </div>

      <!-- CSV上传弹窗 -->
      <a-modal
        v-model:visible="showCsvUploadModal"
        title="上传CSV知识文件"
        width="500px"
        :footer="null"
        @cancel="resetCsvUpload"
      >
        <div class="csv-upload-content">
          <div class="upload-description">
            <p>请选择包含知识图谱数据的CSV文件</p>
            <p class="upload-tips">
              <IconInfoCircle />
              支持格式：节点数据、关系数据等结构化知识内容
            </p>
          </div>

          <a-upload
            ref="csvUploadRef"
            :file-list="csvFileList"
            :before-upload="beforeCsvUpload"
            @change="handleCsvUploadChange"
            accept=".csv"
            :limit="1"
            :auto-upload="false"
            drag
          >
            <template #upload-button>
              <div class="upload-drag-area">
                <div class="upload-drag-icon">
                  📁
                </div>
                <div class="upload-drag-text">
                  <p>点击或拖拽CSV文件到此处</p>
                  <p class="upload-drag-hint">仅支持.csv格式文件，单个文件不超过10MB</p>
                </div>
              </div>
            </template>
          </a-upload>

          <div class="upload-actions" v-if="csvFileList.length > 0">
            <a-button @click="resetCsvUpload" style="margin-right: 12px;">
              重新选择
            </a-button>
            <a-button 
              type="primary" 
              @click="processCsvFile"
              :loading="isProcessingCsv"
            >
              开始处理
            </a-button>
          </div>
        </div>
      </a-modal>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import { message } from 'ant-design-vue'
import {
  IconArrowLeft,
  IconRefresh,
  IconUndo,
  IconFullscreen,
  IconCamera,
  IconUpload,
  IconInfoCircle
} from '@arco-design/web-vue/es/icon'
import NetworkRenderer3D from '@/components/3d-network/NetworkRenderer3D.js'
import { StaticGraphDataInterface } from '@/components/3d-network/data/GraphDataInterface.js'
import { managementGraphData, managementNodeTypeColors, managementEdgeTypeStyles } from '@/components/3d-network/data/managementGraphData.js'

const router = useRouter()

// 响应式数据
const networkCanvas = ref(null)
const isLoading = ref(true)
const showLabels = ref(true)
const isSimulating = ref(true)
const layoutMode = ref('force')
const stats = ref({
  nodeCount: 0,
  edgeCount: 0,
  nodeTypes: {},
  edgeTypes: {}
})
const selectedNodeInfo = ref(null)

// CSV上传相关状态
const showCsvUploadModal = ref(false)
const csvFileList = ref([])
const csvUploadRef = ref(null)
const isProcessingCsv = ref(false)

// 3D网络渲染器实例
let networkRenderer = null
let dataInterface = null

// 生命周期
onMounted(async () => {
  await nextTick()
  await initializeNetwork()
  
  // 检查是否从CSV页面跳转过来
  checkForCsvData()
})

onUnmounted(() => {
  if (networkRenderer) {
    networkRenderer.dispose()
  }
})

// 初始化3D网络
async function initializeNetwork() {
  try {
    if (!networkCanvas.value) {
      console.error('Canvas element not found')
      return
    }

    // 创建数据接口
    dataInterface = new StaticGraphDataInterface(
      managementGraphData,
      managementNodeTypeColors,
      managementEdgeTypeStyles
    )

    // 初始化网络渲染器
    networkRenderer = new NetworkRenderer3D(networkCanvas.value)
    
    // 设置回调函数
    networkRenderer.onDataUpdate = handleDataUpdate
    networkRenderer.onNodeClick = handleNodeClick
    
    // 初始化渲染器
    networkRenderer.init()
    
    // 加载数据
    await dataInterface.loadData()
    networkRenderer.loadSailisiData(managementGraphData)
    
    // 更新统计信息
    updateStats()
    
    isLoading.value = false
    console.log('图数据库管理界面初始化完成')
    
  } catch (error) {
    console.error('初始化3D网络失败:', error)
    isLoading.value = false
  }
}

// 检查CSV数据
function checkForCsvData() {
  const route = router.currentRoute.value
  const hasNewData = route.query.hasNewData === 'true'
  const fromCsv = route.query.fromCsv === 'true'
  
  if (hasNewData || fromCsv) {
    // 从sessionStorage获取处理后的图谱数据
    const csvGraphData = sessionStorage.getItem('csvGraphData')
    if (csvGraphData) {
      try {
        const graphData = JSON.parse(csvGraphData)
        if (graphData && graphData.nodes && graphData.nodes.length > 0) {
          // 加载新的图谱数据
          loadNewGraphData(graphData)
          
          // 显示成功消息
          message.success('CSV数据处理完成！已加载新的图谱数据')
          
          // 清除URL参数
          router.replace({ path: '/graph-management' })
        }
      } catch (error) {
        console.error('解析CSV图谱数据时出错:', error)
        message.error('加载CSV图谱数据失败')
      }
    }
  }
}

// 加载新的图谱数据
function loadNewGraphData(graphData) {
  if (networkRenderer && graphData) {
    try {
      // 更新网络渲染器的数据
      networkRenderer.loadSailisiData(graphData)
      
      // 更新统计信息
      updateStats()
      
      console.log('新的图谱数据已加载:', graphData)
    } catch (error) {
      console.error('加载新图谱数据时出错:', error)
      message.error('加载图谱数据失败')
    }
  }
}

// 处理数据更新
function handleDataUpdate(data) {
  // 数据更新处理，移除频繁的控制台输出
}

// 处理节点点击
function handleNodeClick(nodeIndex, nodeInfo) {
  selectedNodeInfo.value = nodeInfo
  console.log('节点点击:', nodeInfo)
}

// 更新统计信息
function updateStats() {
  if (dataInterface) {
    stats.value = dataInterface.getStats()
  }
}

// 设置布局模式
function setLayoutMode(mode) {
  layoutMode.value = mode
  if (networkRenderer) {
    networkRenderer.setLayoutMode(mode)
  }
}

// 切换标签显示
function toggleLabels(show) {
  if (networkRenderer) {
    networkRenderer.toggleLabels(show)
  }
}

// 切换物理模拟
function toggleSimulation(enabled) {
  if (networkRenderer) {
    networkRenderer.setSimulation(enabled)
  }
}

// 重置相机
function resetCamera() {
  if (networkRenderer) {
    networkRenderer.resetCamera()
  }
}

// 重置布局
function resetLayout() {
  if (networkRenderer) {
    networkRenderer.resetLayout()
  }
}

// 切换全屏
function toggleFullscreen() {
  const container = document.querySelector('.visualization-area')
  if (container) {
    if (!document.fullscreenElement) {
      container.requestFullscreen()
    } else {
      document.exitFullscreen()
    }
  }
}

// 导出图片
function exportImage() {
  if (networkRenderer && networkRenderer.renderer) {
    const canvas = networkRenderer.renderer.domElement
    const link = document.createElement('a')
    link.download = 'graph-management-' + new Date().toISOString().slice(0, 10) + '.png'
    link.href = canvas.toDataURL()
    link.click()
  }
}

// 返回资源中心
function goBack() {
  router.push('/knowledge-base')
}

// CSV上传相关方法
const beforeCsvUpload = (file) => {
  const isCSV = file.type === 'text/csv' || file.name.toLowerCase().endsWith('.csv')
  if (!isCSV) {
    console.error('只能上传CSV格式的文件!')
    return false
  }
  
  const isLt10M = file.size / 1024 / 1024 < 10
  if (!isLt10M) {
    console.error('文件大小不能超过10MB!')
    return false
  }
  
  return false // 阻止自动上传
}

const handleCsvUploadChange = (fileList) => {
  csvFileList.value = fileList
}

const resetCsvUpload = () => {
  csvFileList.value = []
  showCsvUploadModal.value = false
  isProcessingCsv.value = false
}

const processCsvFile = async () => {
  if (csvFileList.value.length === 0) {
    message.warning('请先选择CSV文件')
    return
  }

  isProcessingCsv.value = true
  
  try {
    // 获取实际的File对象
    const fileItem = csvFileList.value[0]
    let file = null
    
    // 处理不同的文件对象结构
    if (fileItem.originFileObj) {
      file = fileItem.originFileObj  // Ant Design Vue upload 组件格式
    } else if (fileItem instanceof File) {
      file = fileItem  // 直接的File对象
    } else if (fileItem.file) {
      file = fileItem.file  // 其他可能的包装格式
    } else {
      file = fileItem  // 尝试直接使用
    }
    
    if (!file || !(file instanceof File)) {
      throw new Error('无法获取有效的文件对象')
    }
    
    // 调用后端API处理CSV文件
    const backendUrl = 'http://localhost:5000'
    
    // 检查后端服务是否可用
    try {
      const healthResponse = await fetch(`${backendUrl}/api/health`)
      if (!healthResponse.ok) {
        throw new Error('后端服务不可用')
      }
    } catch (error) {
      message.error('无法连接到后端服务，请确保Graph Backend正在运行 (http://localhost:5000)')
      isProcessingCsv.value = false
      return
    }
    
    // 上传文件到后端
    const formData = new FormData()
    formData.append('file', file)
    
    const response = await fetch(`${backendUrl}/api/upload-csv`, {
      method: 'POST',
      body: formData
    })
    
    if (!response.ok) {
      throw new Error(`HTTP错误: ${response.status}`)
    }
    
    const result = await response.json()
    
    if (!result.success) {
      throw new Error(result.message || '后端处理失败')
    }
    
    // 关闭弹窗并重置
    resetCsvUpload()
    
    // 显示成功消息
    message.success('CSV文件处理成功！')
    
    // 跳转到CSV图谱分析页面
    router.push({
      path: '/csv-graph',
      query: {
        hasData: 'true'
      }
    })
    
    // 将数据存储到sessionStorage以便结果页面使用
    sessionStorage.setItem('csvGraphData', JSON.stringify(result))
    
  } catch (error) {
    console.error('处理CSV文件时出错:', error)
    message.error('文件处理失败: ' + error.message)
    isProcessingCsv.value = false
  }
}

// 读取文件为文本
const readFileAsText = (file) => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.onload = (e) => resolve(e.target.result)
    reader.onerror = (e) => reject(e)
    reader.readAsText(file, 'UTF-8')
  })
}

// 解析CSV文本
const parseCSV = (text) => {
  if (!text || typeof text !== 'string') {
    throw new Error('无效的CSV文本')
  }
  
  const lines = text.trim().split('\n').filter(line => line && line.trim())
  if (lines.length < 2) {
    throw new Error('CSV文件至少需要包含标题行和一行数据')
  }

  // 更健壮的CSV解析
  const parseCSVLine = (line) => {
    const result = []
    let current = ''
    let inQuotes = false
    
    for (let i = 0; i < line.length; i++) {
      const char = line[i]
      if (char === '"') {
        inQuotes = !inQuotes
      } else if (char === ',' && !inQuotes) {
        result.push(current.trim().replace(/^"|"$/g, ''))
        current = ''
      } else {
        current += char
      }
    }
    result.push(current.trim().replace(/^"|"$/g, ''))
    return result
  }

  const headers = parseCSVLine(lines[0]).filter(h => h && h.trim())
  const data = []

  for (let i = 1; i < lines.length; i++) {
    const values = parseCSVLine(lines[i])
    if (values.length >= headers.length) {
      const row = {}
      headers.forEach((header, index) => {
        row[header] = values[index] || ''
      })
      data.push(row)
    }
  }

  return { headers, data }
}

// 处理数据为图谱格式
const processDataToGraph = (csvData, fileName) => {
  const { headers, data } = csvData
  
  // 自动检测关系列
  let sourceCol = null, targetCol = null, relationCol = null
  
  // 常见的源列名
  const sourcePatterns = ['source', 'from', 'start', '源', '起点', '主体', '实体1']
  const targetPatterns = ['target', 'to', 'end', '目标', '终点', '客体', '实体2']  
  const relationPatterns = ['relation', 'relationship', 'type', 'edge', '关系', '类型', '连接']

  // 查找匹配的列
  for (const header of headers) {
    const lowerHeader = header.toLowerCase()
    if (!sourceCol && sourcePatterns.some(p => lowerHeader.includes(p.toLowerCase()))) {
      sourceCol = header
    }
    if (!targetCol && targetPatterns.some(p => lowerHeader.includes(p.toLowerCase()))) {
      targetCol = header
    }
    if (!relationCol && relationPatterns.some(p => lowerHeader.includes(p.toLowerCase()))) {
      relationCol = header
    }
  }

  // 如果没有找到标准列名，使用前几列
  if (!sourceCol && headers.length >= 2) sourceCol = headers[0]
  if (!targetCol && headers.length >= 2) targetCol = headers[1]
  if (!relationCol && headers.length >= 3) relationCol = headers[2]

  const nodes = new Map()
  const edges = []

  // 处理每行数据
  data.forEach((row, index) => {
    const source = row[sourceCol]
    const target = row[targetCol]
    const relation = relationCol ? row[relationCol] : '关联'

    if (!source || !target || source === target) return

    // 添加节点
    if (!nodes.has(source)) {
      nodes.set(source, {
        id: source,
        name: source,
        type: 'entity',
        group: 1,
        category: '实体'
      })
    }

    if (!nodes.has(target)) {
      nodes.set(target, {
        id: target,
        name: target,
        type: 'entity',
        group: 2,
        category: '实体'
      })
    }

    // 添加边
    edges.push({
      id: `edge_${index}`,
      source: source,
      target: target,
      type: relation || '关联',
      weight: 1,
      time: new Date().toISOString()
    })
  })

  return {
    metadata: {
      title: fileName.replace(/\.[^/.]+$/, ''),
      description: `从${fileName}导入的知识图谱`,
      nodeCount: nodes.size,
      edgeCount: edges.length,
      lastModified: new Date().toISOString()
    },
    nodes: Array.from(nodes.values()),
    edges: edges
  }
}

</script>

<style scoped>
.graph-management-page {
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: #f5f5f5;
}

.page-header {
  background: white;
  padding: 20px 24px;
  border-bottom: 1px solid #e8e8e8;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.page-header h2 {
  margin: 0 0 4px 0;
  color: #262626;
  font-size: 24px;
  font-weight: 600;
}

.page-header p {
  margin: 0;
  color: #8c8c8c;
  font-size: 14px;
}

.header-actions {
  display: flex;
  gap: 12px;
}

.management-container {
  flex: 1;
  display: flex;
  gap: 16px;
  padding: 16px;
  min-height: 0;
}

.control-panel {
  width: 280px;
  background: white;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  display: flex;
  flex-direction: column;
  gap: 24px;
  max-height: calc(100vh - 120px);
  overflow-y: auto;
}

.panel-section h3 {
  margin: 0 0 16px 0;
  color: #262626;
  font-size: 16px;
  font-weight: 600;
  border-bottom: 1px solid #f0f0f0;
  padding-bottom: 8px;
}

.control-group {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}

.control-label {
  color: #595959;
  font-size: 14px;
}

.stats-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}

.stat-item {
  text-align: center;
  padding: 12px;
  background: #fafafa;
  border-radius: 6px;
}

.stat-value {
  font-size: 20px;
  font-weight: 600;
  color: #1890ff;
  margin-bottom: 4px;
}

.stat-label {
  font-size: 12px;
  color: #8c8c8c;
}

.node-info {
  background: #fafafa;
  border-radius: 6px;
  padding: 12px;
}

.info-row {
  display: flex;
  justify-content: space-between;
  margin-bottom: 8px;
}

.info-row:last-child {
  margin-bottom: 0;
}

.info-label {
  color: #8c8c8c;
  font-size: 13px;
}

.info-value {
  color: #262626;
  font-size: 13px;
  font-weight: 500;
}

.no-selection {
  color: #bfbfbf;
  font-size: 13px;
  text-align: center;
  padding: 20px;
}

.visualization-area {
  flex: 1;
  position: relative;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  overflow: hidden;
}

.canvas-container {
  width: 100%;
  height: 100%;
  position: relative;
}

.network-canvas {
  width: 100%;
  height: 100%;
  display: block;
  background: #0a0a0a;
}

.loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.8);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10;
}

.loading-overlay .arco-spin {
  color: white;
}

.toolbar {
  position: absolute;
  top: 16px;
  right: 16px;
  display: flex;
  gap: 8px;
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(8px);
  border-radius: 8px;
  padding: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}

.toolbar .arco-btn {
  width: 32px;
  height: 32px;
  border-radius: 6px;
}

/* 响应式设计 */
@media (max-width: 1200px) {
  .management-container {
    flex-direction: column;
  }
  
  .control-panel {
    width: 100%;
    max-height: 300px;
    order: 2;
  }
  
  .visualization-area {
    order: 1;
    min-height: 400px;
  }
}

/* 全屏模式样式 */
:fullscreen .visualization-area {
  border-radius: 0;
}

:fullscreen .toolbar {
  top: 20px;
  right: 20px;
}

/* CSV上传按钮样式 */
.csv-upload-button {
  position: absolute;
  bottom: 20px;
  left: 20px;
  z-index: 100;
}

.csv-upload-button .upload-btn {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border: none;
  border-radius: 8px;
  box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
  transition: all 0.3s ease;
}

.csv-upload-button .upload-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(102, 126, 234, 0.6);
}

/* CSV上传弹窗样式 */
.csv-upload-content {
  padding: 16px 0;
}

.upload-description {
  margin-bottom: 24px;
}

.upload-description p {
  margin: 0 0 8px 0;
  color: #333;
}

.upload-tips {
  display: flex;
  align-items: center;
  gap: 8px;
  color: #666;
  font-size: 14px;
  background: #f5f5f5;
  padding: 8px 12px;
  border-radius: 6px;
  margin-top: 12px;
}

.upload-drag-area {
  text-align: center;
  padding: 40px 20px;
  border: 2px dashed #d9d9d9;
  border-radius: 8px;
  background: #fafafa;
  transition: all 0.3s ease;
}

.upload-drag-area:hover {
  border-color: #667eea;
  background: #f0f2ff;
}

.upload-drag-icon {
  font-size: 48px;
  color: #d9d9d9;
  margin-bottom: 16px;
}

.upload-drag-text p {
  margin: 0 0 4px 0;
  color: #333;
}

.upload-drag-hint {
  color: #999;
  font-size: 12px;
}

.upload-actions {
  margin-top: 20px;
  text-align: right;
}
</style>
